/*
ont-space - The ontology-based resource metadata repository
Copyright (c) 2006-2008, Information Eng. Research Unit - Univ. of Alcalá
http://www.cc.uah.es/ie
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.ontspace.util.translator.lom2owl.owl;

import java.io.*;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.RDFNode;


import org.ieee.ltsc.datatype.Duration;
import org.ieee.ltsc.datatype.Duration.*;
import org.ieee.ltsc.lom.LOM;
import org.ieee.ltsc.lom.LOMUtil;

/**
 * Translates a LOM educational element to its representation in OWL. 
 */
public class E2ETranslator extends ElementTranslatorImpl {

    private String category =
            new String();
    private String attributeName =
            new String();
    private String element =
            new String();

    /** Creates a new instance of E2ETranslator */
    public E2ETranslator(String elementCategory, String elementElement,
            String elementAttribute) {

        this.category =
                elementCategory;
        this.attributeName =
                elementAttribute;
        this.element =
                elementElement;
    }

    /**
     * This method translates a LOM educational element to its representation 
     * in OWL. 
     * @param lom The metadata record
     * @param ont The ontology
     * @param inst The instance of learning Object
     * @param nsName The namespace
     * @param errorWriter The error file
     */
    public void apply(LOM lom, OntModel ont, Individual inst, String nsName,
            PrintWriter errorWriter) {
        OntClass lomEducationalClass =
                ont.getOntClass(nsName + "#lomEducational");
        OntClass langStringClass =
                ont.getOntClass(nsName + "#langString");
        OntClass singleLangStringClass =
                ont.getOntClass(nsName +
                "#singleLangString");
        OntClass durationClass =
                ont.getOntClass(nsName + "#lomDuration");

        DatatypeProperty interactivityTypeProperty =
                ont.getDatatypeProperty(nsName + "#hasInteractivityType");
        DatatypeProperty learningProperty =
                ont.getDatatypeProperty(nsName +
                "#hasLearningResourceType");
        DatatypeProperty interactivityLevelProperty =
                ont.getDatatypeProperty(nsName + "#hasInteractivityLevel");
        DatatypeProperty semanticProperty =
                ont.getDatatypeProperty(nsName +
                "#hasSemanticDensity");
        DatatypeProperty intendedProperty =
                ont.getDatatypeProperty(nsName +
                "#isIntentedForUserRole");
        DatatypeProperty hasValueProperty =
                ont.getDatatypeProperty(nsName +
                "#hasValue");
        DatatypeProperty inLanguageProperty =
                ont.getDatatypeProperty(nsName +
                "#inLanguage");
        DatatypeProperty difficultyProperty =
                ont.getDatatypeProperty(nsName +
                "#hasDifficulty");
        DatatypeProperty contextProperty =
                ont.getDatatypeProperty(nsName +
                "#isIntendedForContext");
        DatatypeProperty durationProperty =
                ont.getDatatypeProperty(nsName +
                "#hasDurationValue");

        ObjectProperty descriptionProperty =
                ont.getObjectProperty(nsName +
                "#hasDescriptionOnUse");
        ObjectProperty typicalProperty =
                ont.getObjectProperty(nsName +
                "#hasTypicalAgeRange");
        ObjectProperty includeLangStringProperty =
                ont.getObjectProperty(nsName + "#includesSingleLangString");
        ObjectProperty durationDescriptionProperty =
                ont.getObjectProperty(nsName + "#hasDurationDescription");

        String instance =
                null;

        int i =
                0;

        while (LOMUtil.getEducational(lom, i) != null) {
            instance =
                    "#edu-" +
                    inst.getLocalName() + "-" + String.valueOf(i);

            Individual instanceEducational =
                    ont.createIndividual(nsName +
                    instance, lomEducationalClass);

            //5.1 interactivityType 
            String interactivityTypeLOM =
                    LOMUtil.getValue(LOMUtil.getEducationalInteractivityType(lom,
                    i));

            if (interactivityTypeLOM != null) {
                RDFNode interactivityValue =
                        ont.createTypedLiteral(interactivityTypeLOM);
                instanceEducational.setPropertyValue(interactivityTypeProperty,
                        interactivityValue);
            } else {
                String log =
                        "The Difficulty field of the Educational category must contain a value";
                errorWriter.println(log);
            }

            //5.2 learningResourceType
            String learningLOM =
                    "";
            int j =
                    0;

            while (LOMUtil.getEducationalLearningResourceType(lom, i, j) != null) {
                learningLOM =
                        LOMUtil.getValue(LOMUtil.getEducationalLearningResourceType(lom,
                        i, j));

                if (learningLOM != null) {
                    RDFNode learningValue =
                            ont.createTypedLiteral(learningLOM);
                    instanceEducational.addProperty(learningProperty,
                            learningValue);
                }
                j++;
            }
            //5.3 interactivity level

            String interactivityLOM =
                    LOMUtil.getValue(LOMUtil.getEducationalInteractivityLevel(lom,
                    i));

            if (interactivityLOM != null) {
                RDFNode interactivityValue =
                        ont.createTypedLiteral(interactivityLOM);
                instanceEducational.setPropertyValue(interactivityLevelProperty,
                        interactivityValue);
            } else {
                String log =
                        "The InteractivityLevel field of the Educational category must contain a value";
                errorWriter.println(log);
            }

            //5.4 semantic density               

            String semanticLOM =
                    LOMUtil.getValue(LOMUtil.getEducationalSemanticDensity(lom,
                    i));

            if (semanticLOM != null) {
                RDFNode semanticValue =
                        ont.createTypedLiteral(semanticLOM);
                instanceEducational.setPropertyValue(semanticProperty,
                        semanticValue);
            } else {
                String log =
                        "The Semantic field of the Educational category must contain a value";
                errorWriter.println(log);
            }

            //5.5 intended end user role
            String intendedLOM =
                    "";
            j =
                    0;

            while (LOMUtil.getEducationalIntendedEndUserRole(lom, i, j) != null) {
                intendedLOM =
                        LOMUtil.getValue(LOMUtil.getEducationalIntendedEndUserRole(lom,
                        i, j));

                if (intendedLOM != null) {
                    RDFNode intendedValue =
                            ont.createTypedLiteral(intendedLOM);
                    instanceEducational.addProperty(intendedProperty,
                            intendedValue);
                }
                j++;
            }

            //5.6 context
            String contextLOM =
                    "";
            j =
                    0;
            while (LOMUtil.getEducationalContext(lom, i, j) != null) {
                contextLOM =
                        LOMUtil.getValue(LOMUtil.getEducationalContext(lom,
                        i, j));

                if (contextLOM != null) {
                    RDFNode contextValue =
                            ont.createTypedLiteral(contextLOM);
                    instanceEducational.addProperty(contextProperty,
                            contextValue);
                }
                j++;
            }
            //5.7 typical age range

            j =
                    0;
            int k =
                    0;


            while (LOMUtil.getEducationalTypicalAgeRange(lom, i, j) != null) {
                instance =
                        "#lsEduAge" +
                        inst.getLocalName() + "-" + String.valueOf(j);

                Individual langInstance =
                        ont.createIndividual(nsName + instance, langStringClass);
                k =
                        0;
                while (LOMUtil.getString(LOMUtil.getEducationalTypicalAgeRange(lom,
                        i, j), k) != null) {
                    String typicalageLOM =
                            LOMUtil.getString(LOMUtil.getEducationalTypicalAgeRange(lom,
                            i, j), k);
                    String languageLOM =
                            LOMUtil.getLanguage(LOMUtil.getEducationalTypicalAgeRange(lom,
                            i, j), k);

                    instance =
                            "#slsEduAge" +
                            inst.getLocalName() + "-" + String.valueOf(i);

                    Individual singleInstance =
                            ont.createIndividual(nsName +
                            instance, singleLangStringClass);

                    if (typicalageLOM != null) {
                        RDFNode typicalValue =
                                ont.createTypedLiteral(typicalageLOM);
                        singleInstance.setPropertyValue(hasValueProperty,
                                typicalValue);
                    } else {
                        String log =
                                "The TyipcalAge field of the Educational category must contain a value";
                        errorWriter.println(log);
                    }
                    if (languageLOM != null) {
                        RDFNode languageValue =
                                ont.createTypedLiteral(languageLOM);
                        singleInstance.setPropertyValue(inLanguageProperty,
                                languageValue);
                    } else {
                        String log =
                                "The Language field of TypicalAge in the Educational category must contain a value";
                        errorWriter.println(log);
                    }

                    langInstance.addProperty(includeLangStringProperty,
                            singleInstance);
                    k++;
                }
                j++;

                instanceEducational.addProperty(typicalProperty, langInstance);
            }


            //5.8 difficulty
            String difficultyLOM =
                    "";


            difficultyLOM =
                    LOMUtil.getValue(LOMUtil.getEducationalDifficulty(lom, i));

            if (difficultyLOM != null) {
                RDFNode difficultyValue =
                        ont.createTypedLiteral(difficultyLOM);
                instanceEducational.addProperty(difficultyProperty,
                        difficultyValue);
            } else {
                String log =
                        "The Difficulty field of the Educational category must contain a value";
                errorWriter.println(log);

            }
            //5.9 typical learning time
            //create the duration instance   
            try {
                Duration tDuration =
                        null;
                Description desc1 =
                        null;
                tDuration =
                        LOMUtil.getEducationalTypicalLearningTime(lom, i);
                if (tDuration != null) {
                    desc1 =
                            tDuration.description();
                    String dur =
                            String.valueOf(LOMUtil.getDuration(tDuration.value()));

                    //duration value
                    instance =
                            "#eduD" +
                            inst.getLocalName() + "-" + String.valueOf(i);

                    Individual durationInstance =
                            ont.createIndividual(nsName +
                            instance, durationClass);
                    if (dur != null) {
                        RDFNode durationValue =
                                ont.createTypedLiteral(dur);
                        durationInstance.setPropertyValue(durationProperty,
                                durationValue);
                    }

                    //duration description (langstring)     
                    instance =
                            "#lsEduDD" +
                            inst.getLocalName() + "-" + String.valueOf(i);

                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);
                    j =
                            0;
                    while ((LOMUtil.getString(LOMUtil.getDescription(tDuration),
                            j)) != null) {
                        instance =
                                "#slsEduDD" +
                                inst.getLocalName() + "-" + String.valueOf(j);

                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);
                        String elementLOM =
                                LOMUtil.getString(desc1, j);
                        String languageLOM =
                                LOMUtil.getLanguage(desc1, j);
                        if (elementLOM != null) {
                            RDFNode elementValue =
                                    ont.createTypedLiteral(elementLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    elementValue);
                        } else {
                            String log =
                                    "The Description field of TypicalLearningTime of the Educational category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of Description TypicalLearningTime of the Educational category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);
                        j++;
                    }
                    durationInstance.setPropertyValue(durationDescriptionProperty,
                            langInstance);
                    ObjectProperty typicalLearningProperty =
                            ont.getObjectProperty(nsName +
                            "#hasTypicalLearningTime");
                    instanceEducational.setPropertyValue(typicalLearningProperty,
                            durationInstance);
                }//if
                else {
                    String log =
                            "The TypicalLearningTime field of the Educational category must contain a value";
                    errorWriter.println(log);
                }


            } catch (Exception e) {
            }

            //5.10 description                                           
            j =
                    0;

            while (LOMUtil.getEducationalDescription(lom, i, j) != null) {
                instance =
                        "#lsEduDescr" +
                        inst.getLocalName() + "-" + String.valueOf(j);

                Individual langInstance1 =
                        ont.createIndividual(nsName +
                        instance, langStringClass);
                k =
                        0;
                while (LOMUtil.getString(LOMUtil.getEducationalDescription(lom,
                        i, j), k) != null) {
                    String educationaldescriptionLOM =
                            LOMUtil.getString(LOMUtil.getEducationalDescription(lom,
                            i, j), k);
                    String languageLOM =
                            LOMUtil.getLanguage(LOMUtil.getEducationalDescription(lom,
                            i, j), k);

                    instance =
                            "#slsEduDescr" +
                            inst.getLocalName() + "-" + String.valueOf(k);
                    Individual singleInstance =
                            ont.createIndividual(nsName +
                            instance, singleLangStringClass);

                    if (educationaldescriptionLOM != null) {
                        RDFNode descriptionValue =
                                ont.createTypedLiteral(educationaldescriptionLOM);
                        singleInstance.setPropertyValue(hasValueProperty,
                                descriptionValue);
                    } else {
                        String log =
                                "The Description field of the Educational category must contain a value";
                        errorWriter.println(log);
                    }
                    if (languageLOM != null) {
                        RDFNode languageValue =
                                ont.createTypedLiteral(languageLOM);
                        singleInstance.setPropertyValue(inLanguageProperty,
                                languageValue);
                    } else {
                        String log =
                                "The Language field of Description in the Educational category must contain a value";
                        errorWriter.println(log);
                    }

                    langInstance1.addProperty(includeLangStringProperty,
                            singleInstance);

                    k++;

                }
                instanceEducational.addProperty(descriptionProperty,
                        langInstance1);
                j++;
                k =
                        0;
            }




            //5.11 language 

            String languageLOM =
                    "";
            DatatypeProperty languageProperty =
                    ont.getDatatypeProperty(nsName +
                    "#hasHumanLanguage");
            j =
                    0;
            while (LOMUtil.getEducationalLanguage(lom, i, j) != null) {

                languageLOM =
                        LOMUtil.getString(LOMUtil.getEducationalLanguage(lom, i,
                        j));

                if (languageLOM != null) {
                    RDFNode languageValue =
                            ont.createTypedLiteral(languageLOM);
                    instanceEducational.addProperty(languageProperty,
                            languageValue);
                }
                j++;
            }


            i++;
            ObjectProperty educationalProperty =
                    ont.getObjectProperty(nsName +
                    "#hasEducationalInformation");
            inst.addProperty(educationalProperty, instanceEducational);
        }

    }
}
